use std::{
    fs,
    io::{self, Write},
    path::{Path, PathBuf},
};

// 定义内存区域大小和图像尺寸 (必须与Python脚本一致)
pub const SYS_SEGMENT_SIZE: usize = 1024; // 1KB for System Segment
pub const PUB_SEGMENT_WIDTH: usize = 128;
pub const PUB_SEGMENT_HEIGHT: usize = 128;
pub const PUB_SEGMENT_SIZE: usize = PUB_SEGMENT_WIDTH * PUB_SEGMENT_HEIGHT; // 16KB for Public Segment (128x128 pixels, 1 byte per pixel)
pub const TOTAL_MEMORY_SIZE: usize = SYS_SEGMENT_SIZE + PUB_SEGMENT_SIZE; // Total 17KB

/// (不再由Rust主程序调用，但作为模块工具保留)
/// 初始化 `mem.img` 文件，填充0
#[allow(dead_code)] // 允许此函数未被使用，因为它现在由Python脚本负责
pub fn init_mem_img(path: &Path) -> io::Result<()> {
    if path.exists() {
        println!("INFO: mem.img already exists at {:?}, skipping initialization.", path);
        return Ok(());
    }

    println!("INFO: Initializing new mem.img at {:?}", path);
    let mut file = fs::File::create(path)?;
    let initial_data = vec![0u8; TOTAL_MEMORY_SIZE];
    file.write_all(&initial_data)?;
    println!("INFO: mem.img initialized successfully.");
    Ok(())
}

/// 从文件加载 `mem.img` 的内容到内存
pub fn load_mem_img(path: &Path) -> io::Result<Vec<u8>> {
    // println!("INFO: Loading mem.img from {:?}", path); // 减少日志噪音
    let data = fs::read(path)?;
    if data.len() != TOTAL_MEMORY_SIZE {
        return Err(io::Error::new(
            io::ErrorKind::InvalidData,
            format!(
                "mem.img size mismatch. Expected {} bytes, found {} bytes. \
                Please ensure mem.img is correctly initialized by the Python script.",
                TOTAL_MEMORY_SIZE,
                data.len()
            ),
        ));
    }
    // println!("INFO: mem.img loaded successfully. Size: {} bytes.", data.len()); // 减少日志噪音
    Ok(data)
}

/// 原子性地保存内存内容到 `mem.img`
/// 通过写入临时文件然后重命名来保证原子性，防止数据损坏。
pub fn save_mem_img(path: &Path, data: &[u8]) -> io::Result<()> {
    if data.len() != TOTAL_MEMORY_SIZE {
        return Err(io::Error::new(
            io::ErrorKind::InvalidData,
            format!(
                "Data size mismatch for saving. Expected {} bytes, found {} bytes.",
                TOTAL_MEMORY_SIZE,
                data.len()
            ),
        ));
    }

    let temp_path = PathBuf::from(format!("{}.tmp", path.to_string_lossy()));
    // println!( // 减少日志噪音
    //     "INFO: Saving mem.img atomically to {:?}, using temp file {:?}",
    //     path, temp_path
    // );

    let mut temp_file = fs::File::create(&temp_path)?;
    temp_file.write_all(data)?;
    temp_file.sync_all()?; // 确保数据写入磁盘

    fs::rename(&temp_path, path)?; // 原子重命名
    // println!("INFO: mem.img saved successfully."); // 减少日志噪音
    Ok(())
}

/// 将 (x, y) 坐标映射到公共区内存中的偏移量
/// x 和 y 必须在 [0, PUB_SEGMENT_WIDTH-1] 和 [0, PUB_SEGMENT_HEIGHT-1] 范围内
pub fn pub_coords_to_offset(x: usize, y: usize) -> Option<usize> {
    if x < PUB_SEGMENT_WIDTH && y < PUB_SEGMENT_HEIGHT {
        // 公共区从系统区之后开始
        Some(SYS_SEGMENT_SIZE + y * PUB_SEGMENT_WIDTH + x)
    } else {
        None // 坐标超出公共区范围
    }
}